<template>
    <div class="nav-bar">
        <div class="left-button">
            <button class="button-com" @click="handleScroll(240)">
                <i class="el-icon-caret-left"></i>
            </button>
        </div>
        <div class="scroll-outer" ref="scrollOuter" @DOMMouseScroll="handlescroll" @mousewheel="handlescroll">
            <div class="scroll-body" ref="scrollBody" :style="{ left: tabBodyLeft + 'px' }">
                <div v-for="item in tabList" class="tab-ct" :class="{ 'current': isCurrentTab(item) }" :key="item.name"
                    @click="onTabClick(item)" @mouseup.middle="onCloseClick(item)" ref="tabsPageOpened">
                    <span class="dot"></span>
                    <span class="tab-ct-label">{{ item.label }}</span>
                    <i class="close el-icon-close" v-if="item.closable" @click.stop="onCloseClick(item)"></i>
                </div>
            </div>
        </div>
        <div class="right-button">
            <button class="button-com" @click="handleScroll(-240)">
                <i class="el-icon-caret-right"></i>
            </button>
        </div>
    </div>
</template>

<script>
    import { mapState, mapMutations } from 'vuex'
    export default {
        name: 'navigatorTab',
        data() {
            return {
                tabBodyLeft: 0,
                outerPadding: 4,
            }
        },
        computed: {
            ...mapState(['tabList', 'activeTab'])
        },
        watch: {
            activeTab: {
                immediate: true,
                deep: true,
                handler() {
                    // 把标签滚动回到可是区域
                    this.$nextTick(() => {
                        if (!this.tabList?.length) return
                        var nowItem = this.tabList.filter(item => item.path == this.activeTab)[0];
                        var tabIndex = this.tabList.indexOf(nowItem);
                        let tab = this.$refs.tabsPageOpened[tabIndex];
                        const outerWidth = this.$refs.scrollOuter.offsetWidth
                        const bodyWidth = this.$refs.scrollBody.offsetWidth
                        if (bodyWidth < outerWidth) {
                            this.tabBodyLeft = 0
                        } else if (tab.offsetLeft < -this.tabBodyLeft) {
                            // 标签在可视区域左侧
                            this.tabBodyLeft = -tab.offsetLeft + this.outerPadding
                        } else if (tab.offsetLeft > -this.tabBodyLeft && tab.offsetLeft + tab.offsetWidth < -this.tabBodyLeft + outerWidth) {
                            // 标签在可视区域
                            this.tabBodyLeft = Math.min(0, outerWidth - tab.offsetWidth - tab.offsetLeft - this.outerPadding)
                        } else {
                            // 标签在可视区域右侧
                            this.tabBodyLeft = -(tab.offsetLeft - (outerWidth - this.outerPadding - tab.offsetWidth))
                        }
                    })
                }
            }
        },
        methods: {
            ...mapMutations(['RemoveTabList', 'SetActiveTab']),
            /**
             * tab标签滚动行为
             */
            handlescroll(e) {
                var type = e.type
                let delta = 0
                if (type === 'DOMMouseScroll' || type === 'mousewheel') {
                    delta = (e.wheelDelta) ? e.wheelDelta : -(e.detail || 0) * 40
                }
                this.handleScroll(delta)
            },
            handleScroll(offset) {
                const outerWidth = this.$refs.scrollOuter.offsetWidth
                const bodyWidth = this.$refs.scrollBody.offsetWidth
                if (offset > 0) {
                    this.tabBodyLeft = Math.min(0, this.tabBodyLeft + offset)
                } else {
                    if (outerWidth < bodyWidth) {
                        if (this.tabBodyLeft < -(bodyWidth - outerWidth)) {
                            this.tabBodyLeft = this.tabBodyLeft
                        } else {
                            this.tabBodyLeft = Math.max(this.tabBodyLeft + offset, outerWidth - bodyWidth)
                        }
                    } else {
                        this.tabBodyLeft = 0
                    }
                }
            },
            /**
             * 当前tab样式不一样
             */
            isCurrentTab(item) {
                return this.activeTab == item.path;
            },
            /**
             * 事件触发，触发点击事件，跳转路由
             */
            onTabClick(item) {
                if (this.isCurrentTab(item)) return;
                this.$router.push({
                    path: item.path
                });
                this.SetActiveTab(item.path)
            },
            /**
             * 关闭事件
             * @param {{path:String,label:String,closable:Boolean,component: Vue}} item
             */
            onCloseClick(item) {
                this.RemoveTabList(item.path)
                this.$router.push({
                    path: this.activeTab
                })
            },
        }
    }
</script>

<style scoped lang="less">
    .nav-bar {
        width: 100%;
        height: 60px;
        box-sizing: border-box;
        display: flex;
        user-select: none;

        .button-com {
            height: 100%;
            background: #fff;
            line-height: 1;
            width: 50px;
            border: none;
            cursor: pointer;
            border: 1px solid #eee;
        }

        .button-com:hover {
            color: rgb(6, 21, 220);
            background-color: #ffee00;
        }

        .scroll-outer {
            position: relative;
            height: 100%;
            flex: 1;
            background: #f8f8f8;
            overflow: hidden;

            .scroll-body {
                position: absolute;
                height: 100%;
                padding: 0 5px;
                display: inline-block;
                white-space: nowrap;
                transition: left 0.3s ease;

                .tab-ct {
                    display: inline-block;
                    height: 50px;
                    min-width: 130px;
                    margin: 5px;
                    line-height: 50px;
                    background: #fff;
                    cursor: pointer;
                    border: 1px solid #e8eaec;
                    position: relative;

                    .dot {
                        display: inline-block;
                        width: 12px;
                        height: 12px;
                        // margin-right: 3px;
                        border-radius: 50%;
                        background: #e8eaec;
                        position: absolute;
                        top: 20px;
                        left: 10px;
                    }

                    &.current .dot {
                        background: #409eff;
                    }

                    .tab-ct-label {
                        padding: 0px 25px;
                        font-size: 16px;
                    }

                    .close {
                        display: inline-block;
                        width: 15px;
                        height: 15px;
                        line-height: 15px;
                        position: absolute;
                        top: 3px;
                        right: 4px;
                        border-radius: 50%;
                        text-align: center;
                    }
                }

                .tab-ct:hover {
                    opacity: 0.85;
                    background-color: #ffee00;
                }

                .tab-ct.current {
                    border: 1px solid #409eff;
                }

            }
        }
    }
</style>